#include "GameEditor.h"
#include "TaskManager.h"
#include "IRenderer.h"
#include "SceneGraph.h"
#include "GUINode.h"
#include "MdlFileLoader.h"
#include "ObjModelFile.h"
#include "Settings.h"
#include "ModelFactory.h"
#include "PhysicsTask.h"
#include "GUIConstruction.h"
#include "GameEditorGUI.h"

GameEditor::GameEditor( Pointer<ITask>& timer, Pointer<ITask>& physics, Pointer<ITask>& update, Pointer<ITask>& combat ) : m_entityCounter(0), m_selected(0)
{
#pragma region SetupDefault
	Renderer->BuildFont(HashedString("Arial"), 10);
	
	MdlFile modelFile;
	ObjModelFile file;
	LoadObjModelFile((Settings::getSingleton().getDirectory() + "//Data//Models//sphere.obj").c_str(), file );
	ConvertToMdlFile(file, modelFile);
	modelFile.modelName = "Default";
	//LoadMdlFile(std::string(Settings::getSingleton().getDirectory() + "//Data//Models//cube.mdl"), modelFile );
	CreateModelFromMdl(modelFile);

	System* system = new System();
	system->Initialize();
	PhysicsTask::getSingleton().AddSystem(HashedString("World"), system);

	CreateWorld("Default");
#pragma endregion
#pragma region Camera
	Pointer<INode> camera;
	m_cameraNode = new CameraNode;
	Game._getMainCamera() = m_cameraNode;	
	CopyPointer(m_cameraNode, camera);
	m_cameraNode->Fovy() = 45.0f;
	m_cameraNode->Aspect() = (float)Renderer->getWindowWidth()/(float)Renderer->getWindowHeight();
	m_cameraNode->Near() = 0.1f;
	m_cameraNode->Far() = 1000.0f;
	Renderer->getWindow()->RegisterHandler("OnWindowResizeEvent", Pointer<EventHandler>( new CEventHandler<CameraNode>(m_cameraNode, &CameraNode::OnResize)));
#pragma endregion
	
	GameEditor* gameEditor = this;

	m_inRunningGameState = false;
	m_running = false;
	m_addingDestinationFlag = false;

	gameEditor->setTimer(timer);
	TaskManager::getSingleton().SuspendTask(timer);
	gameEditor->setPhysics(physics);
	TaskManager::getSingleton().SuspendTask(physics);
	gameEditor->setUpdate(update);
	TaskManager::getSingleton().SuspendTask(update);
	gameEditor->setCombat(combat);
	TaskManager::getSingleton().SuspendTask(combat);
	Pointer<GUIComboBox> combobox;
	Pointer<GUITextbox> textbox;

#pragma region GUI
	GUINode* gui;
	Pointer<INode> node = gui = new GUINode();
	
	GameEditorGUI* gameEditorGUI;
	this->m_gameEditorGUI = gameEditorGUI = new GameEditorGUI(this);

	GUIEditorToolboxConstruction( gui, gameEditorGUI );
	GUIEntityListWindowConstruction( gui, gameEditorGUI );
	GUIRigidBodyWindowConstruction( gui, gameEditorGUI );
	GUISceneGraphWindowConstruction( gui, gameEditorGUI );
	GUILoadModelWindowConstruction( gui, gameEditorGUI );
	GUISaveStateWindowConstruction( gui, gameEditorGUI );
	GUILoadStateWindowConstruction( gui, gameEditorGUI );
	GUILoadTextureWindowConstruction( gui, gameEditorGUI );
	GUICreateTerrainWindowConstruction( gui, gameEditorGUI );
	GUISelectableBodyWindowConstruction( gui, gameEditorGUI );
	GUIPropertiesConstruction( gui, gameEditorGUI );
	GUIAIWindowConstruction( gui, gameEditorGUI );
	GUIAIToolboxConstruction( gui, gameEditorGUI );
	GUISetWorldWindowConstruction( gui, gameEditorGUI );
	GUICreateWorldWindowConstruction( gui, gameEditorGUI );
#pragma endregion

	Renderer->getWindow()->RegisterHandler("OnMouseDownLeftEvent", Pointer<EventHandler>( new CEventHandler<GameEditor>(gameEditor, &GameEditor::ReceiveEvent) ));
	Renderer->getWindow()->RegisterHandler("OnMouseMoveEvent", Pointer<EventHandler>( new CEventHandler<GameEditor>(gameEditor, &GameEditor::ReceiveEvent) ));
	Renderer->getWindow()->RegisterHandler("OnKeyPressEvent", Pointer<EventHandler>( new CEventHandler<GameEditor>(gameEditor, &GameEditor::ReceiveEvent) ));
	Renderer->getWindow()->RegisterHandler("OnKeyReleaseEvent", Pointer<EventHandler>( new CEventHandler<GameEditor>(gameEditor, &GameEditor::ReceiveEvent) ));

	SceneGraph::getSingleton().Push_Back(Pointer<INode>(node));
	SceneGraph::getSingleton().Push_Back(Pointer<INode>(camera));
}

void GameEditor::setTimer( Pointer<ITask>& timer )
{
	m_timer = timer;
}
void GameEditor::setUpdate( Pointer<ITask>& update )
{
	m_updates = update;
}
void GameEditor::setPhysics( Pointer<ITask>& physics )
{
	m_physics = physics;
}
void GameEditor::setCombat( Pointer<ITask>& combat )
{
	m_combat = combat;
}
